#!/usr/bin/env python3
"""
Strategy Configuration for Hyperliquid Trading Strategies

This module defines configuration classes for different trading strategies
used with the Hyperliquid connectors in Hummingbot.
"""

from dataclasses import dataclass
from decimal import Decimal
from typing import Optional, Dict, Any


@dataclass
class GridTradingConfig:
    """
    Configuration for Grid Trading Strategy
    """
    # Basic parameters
    trading_pair: str = "ETH-USD"
    grid_levels: int = 10
    grid_spread: Decimal = Decimal("0.01")  # 1%
    order_amount: Decimal = Decimal("0.1")
    
    # Price range
    upper_price: Optional[Decimal] = None
    lower_price: Optional[Decimal] = None
    price_range_percentage: Decimal = Decimal("0.1")  # 10% around current price
    
    # Risk management
    max_orders_per_side: int = 5
    max_total_position: Decimal = Decimal("10.0")
    stop_loss_percentage: Optional[Decimal] = None
    take_profit_percentage: Optional[Decimal] = None
    
    # Rebalancing
    rebalance_threshold: Decimal = Decimal("0.05")  # 5%
    rebalance_interval: int = 300  # 5 minutes
    
    # Order management
    order_refresh_time: int = 60  # 1 minute
    cancel_order_threshold: Decimal = Decimal("0.02")  # 2%
    
    def to_dict(self) -> Dict[str, Any]:
        """Convert config to dictionary"""
        return {
            "trading_pair": self.trading_pair,
            "grid_levels": self.grid_levels,
            "grid_spread": float(self.grid_spread),
            "order_amount": float(self.order_amount),
            "upper_price": float(self.upper_price) if self.upper_price else None,
            "lower_price": float(self.lower_price) if self.lower_price else None,
            "price_range_percentage": float(self.price_range_percentage),
            "max_orders_per_side": self.max_orders_per_side,
            "max_total_position": float(self.max_total_position),
            "stop_loss_percentage": float(self.stop_loss_percentage) if self.stop_loss_percentage else None,
            "take_profit_percentage": float(self.take_profit_percentage) if self.take_profit_percentage else None,
            "rebalance_threshold": float(self.rebalance_threshold),
            "rebalance_interval": self.rebalance_interval,
            "order_refresh_time": self.order_refresh_time,
            "cancel_order_threshold": float(self.cancel_order_threshold)
        }


@dataclass
class FundingArbitrageConfig:
    """
    Configuration for Funding Rate Arbitrage Strategy
    """
    # Basic parameters
    trading_pair: str = "ETH-USD"
    position_size: Decimal = Decimal("1.0")
    min_funding_rate: Decimal = Decimal("0.0001")  # 0.01%
    
    # Position limits
    max_position_size: Decimal = Decimal("10.0")
    max_leverage: Decimal = Decimal("5.0")
    
    # Rebalancing
    rebalance_threshold: Decimal = Decimal("0.05")  # 5%
    funding_check_interval: int = 60  # 1 minute
    
    # Risk management
    max_drawdown: Decimal = Decimal("0.1")  # 10%
    stop_loss_percentage: Optional[Decimal] = None
    
    # Hedging
    hedge_ratio: Decimal = Decimal("1.0")  # 1:1 hedge ratio
    hedge_tolerance: Decimal = Decimal("0.02")  # 2%
    
    def to_dict(self) -> Dict[str, Any]:
        """Convert config to dictionary"""
        return {
            "trading_pair": self.trading_pair,
            "position_size": float(self.position_size),
            "min_funding_rate": float(self.min_funding_rate),
            "max_position_size": float(self.max_position_size),
            "max_leverage": float(self.max_leverage),
            "rebalance_threshold": float(self.rebalance_threshold),
            "funding_check_interval": self.funding_check_interval,
            "max_drawdown": float(self.max_drawdown),
            "stop_loss_percentage": float(self.stop_loss_percentage) if self.stop_loss_percentage else None,
            "hedge_ratio": float(self.hedge_ratio),
            "hedge_tolerance": float(self.hedge_tolerance)
        }


@dataclass
class ConnectorConfig:
    """
    Configuration for Hyperliquid Connectors
    """
    # API credentials (loaded from config)
    api_key: Optional[str] = None
    api_secret: Optional[str] = None
    
    # Network settings
    testnet: bool = True
    base_url: Optional[str] = None
    ws_url: Optional[str] = None
    
    # Connection settings
    request_timeout: int = 30
    heartbeat_interval: int = 30
    max_retries: int = 3
    
    # Rate limiting
    rate_limit_per_second: int = 10
    rate_limit_burst: int = 20
    
    def to_dict(self) -> Dict[str, Any]:
        """Convert config to dictionary"""
        return {
            "api_key": self.api_key,
            "api_secret": self.api_secret,
            "testnet": self.testnet,
            "base_url": self.base_url,
            "ws_url": self.ws_url,
            "request_timeout": self.request_timeout,
            "heartbeat_interval": self.heartbeat_interval,
            "max_retries": self.max_retries,
            "rate_limit_per_second": self.rate_limit_per_second,
            "rate_limit_burst": self.rate_limit_burst
        }


class StrategyConfigManager:
    """
    Manager for strategy configurations
    """
    
    def __init__(self):
        self._grid_config = GridTradingConfig()
        self._funding_config = FundingArbitrageConfig()
        self._connector_config = ConnectorConfig()
    
    @property
    def grid_trading(self) -> GridTradingConfig:
        """Get grid trading configuration"""
        return self._grid_config
    
    @property
    def funding_arbitrage(self) -> FundingArbitrageConfig:
        """Get funding arbitrage configuration"""
        return self._funding_config
    
    @property
    def connector(self) -> ConnectorConfig:
        """Get connector configuration"""
        return self._connector_config
    
    def update_grid_config(self, **kwargs):
        """Update grid trading configuration"""
        for key, value in kwargs.items():
            if hasattr(self._grid_config, key):
                if key in ['grid_spread', 'order_amount', 'upper_price', 'lower_price', 
                          'price_range_percentage', 'max_total_position', 'stop_loss_percentage',
                          'take_profit_percentage', 'rebalance_threshold', 'cancel_order_threshold']:
                    value = Decimal(str(value)) if value is not None else None
                setattr(self._grid_config, key, value)
    
    def update_funding_config(self, **kwargs):
        """Update funding arbitrage configuration"""
        for key, value in kwargs.items():
            if hasattr(self._funding_config, key):
                if key in ['position_size', 'min_funding_rate', 'max_position_size', 
                          'max_leverage', 'rebalance_threshold', 'max_drawdown',
                          'stop_loss_percentage', 'hedge_ratio', 'hedge_tolerance']:
                    value = Decimal(str(value)) if value is not None else None
                setattr(self._funding_config, key, value)
    
    def update_connector_config(self, **kwargs):
        """Update connector configuration"""
        for key, value in kwargs.items():
            if hasattr(self._connector_config, key):
                setattr(self._connector_config, key, value)
    
    def load_from_dict(self, config_dict: Dict[str, Any]):
        """Load configuration from dictionary"""
        if 'grid_trading' in config_dict:
            self.update_grid_config(**config_dict['grid_trading'])
        
        if 'funding_arbitrage' in config_dict:
            self.update_funding_config(**config_dict['funding_arbitrage'])
        
        if 'connector' in config_dict:
            self.update_connector_config(**config_dict['connector'])
    
    def to_dict(self) -> Dict[str, Any]:
        """Convert all configurations to dictionary"""
        return {
            'grid_trading': self._grid_config.to_dict(),
            'funding_arbitrage': self._funding_config.to_dict(),
            'connector': self._connector_config.to_dict()
        }


# Default configuration instance
default_config = StrategyConfigManager()